package cn.net.scp.test.app;

import java.util.concurrent.locks.LockSupport;

public class ThreadMonitorInfo {

    private static final Object MONITOR = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread waitingThread = new Thread(() -> {
            try {
                synchronized (MONITOR) {
                    MONITOR.wait();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "Waiting Thread");
        Thread parkedThread = new Thread(LockSupport::park, "Parked Thread");

        waitingThread.start();
        parkedThread.start();

        waitingThread.join();
        parkedThread.join();
    }

    // Let’s check the thread dump using jstack:

    /*

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.202-b08 mixed mode):

"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007f7c8d093000 nid=0x5107 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Parked Thread" #12 prio=5 os_prio=31 tid=0x00007f7c8a07b000 nid=0x7c03 waiting on condition [0x0000700010994000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:304)
	at cn.net.scp.test.app.ThreadMonitorInfo$$Lambda$2/1329552164.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)

"Waiting Thread" #11 prio=5 os_prio=31 tid=0x00007f7c92856800 nid=0x5a03 in Object.wait() [0x0000700010891000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x000000076ac262c8> (a java.lang.Object)
	at java.lang.Object.wait(Object.java:502)
	at cn.net.scp.test.app.ThreadMonitorInfo.lambda$main$0(ThreadMonitorInfo.java:13)
	- locked <0x000000076ac262c8> (a java.lang.Object)
	at cn.net.scp.test.app.ThreadMonitorInfo$$Lambda$1/1607521710.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:748)
     */

    /*
    While analyzing the thread dump, it’s clear that the parked thread contains less information. Thus, it might create a situation when a certain thread problem, even with a thread dump, would be hard to debug.
    An additional benefit of using specific concurrent structures or specific locks would provide even more context in the thread dumps, giving more information about the application state. Many JVM concurrent mechanisms are using park() internally. However, if a thread dump explains that the thread is waiting, for example, on a CyclicBarrier, it’s waiting for other threads.
     */
}
